package com.witframework.security.dos;

import java.util.Date;
import java.util.Iterator;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DosFilterUtil {
	private Vector<VisitorTime> visitorTimes = new Vector<VisitorTime>();
	private Vector<IP> visitorIps = new Vector<IP>();
	private static DosFilterUtil instance=new DosFilterUtil();

	private int times=10;
	private DosFilterUtil(){}
	public static DosFilterUtil getInstance(){
		return instance;
	}
	public void filter(HttpServletRequest request, HttpServletResponse response) throws DosException{

		String id = ((HttpServletRequest) request).getSession().getId();
		if (id == null)
			id = request.getRemoteAddr();
		long now = new Date().getTime();
		if (findIP(id, now) != null) {
			throw new DosException("Your account was locked,All requests will fail,Connection refused,Try again later.");
		}
		VisitorTime vt = (VisitorTime) findVisitorTime(id, now);
		if (vt == null) {
			vt = new VisitorTime(id);
			vt.setLength(times);
			vt.init();
			visitorTimes.add(vt);
			vt.insert(now);
		} else {
			vt.insert(now);
			long interval = vt.getLast() - vt.getFirst();
			if (vt.getLast() != 0 && interval < 10000) {
				visitorIps.add(new IP(id, now));
				throw new DosException("In a short time request too many times,Connection refused,Try again later.");
			}
		}
	}



	private VisitorTime findVisitorTime(String id, long now) {
		Iterator<VisitorTime> visitorTimesIt=visitorTimes.iterator();
		while(visitorTimesIt.hasNext()){
			VisitorTime vt=visitorTimesIt.next();
			if (vt.getLast() != 0 && now - vt.getLast() > 100000) {
				visitorTimesIt.remove();
			}
			if (vt.getId().equals(id)) {
				return vt;
			}
		}
		return null;
//		for (int i = 0; i < visitorTimes.size(); i++) {
//			VisitorTime vt = visitorTimes.get(i);
//			if (vt.getLast() != 0 && now - vt.getLast() > 100000) {// 100s后移除不活动的用户访问记录，释放内存
//				visitorTimes.remove(i);
//				i = 0;
//			}
//			if (vt.getId().equals(id)) {
//				return vt;
//			}
//		}
//		return null;
	}

	private IP findIP(String id, long now) {
		Iterator<IP> ipIt=visitorIps.iterator();
		while(ipIt.hasNext()){
			IP ip=ipIt.next();
			if (now - ip.createdTime > 60000) {// 60s后解除ip封锁
				ipIt.remove();
			}
			if (ip.id.equals(id)) {
				return ip;
			}
		}
		return null;
//		for (int i = 0; i < visitorIps.size(); i++) {
//			IP ip = visitorIps.get(i);
//			if (now - ip.createdTime > 60000) {// 60s后解除ip封锁
//				visitorIps.remove(i);
//				i = 0;
//			}
//			if (ip.id.equals(id)) {
//				return ip;
//			}
//		}
//		return null;
	}

	class IP {
		IP(String id, long createdTime) {
			this.id = id;
			this.createdTime = createdTime;
		}

		String id;
		long createdTime;
	}

	public void setTimes(int times) {
		this.times = times;
	}
}
